#include "download_channel.h"
#include "base/bind.h"
#include "base/shared_memory.h"
#include "base/utf_string_conversions.h"
#include "utils.h"

// DownloadChannel::IORequest 
// 运行在IO线程内
struct DownloadChannel::IORequest : base::RefCountedThreadSafe<IORequest> {
	explicit IORequest(DownloadChannel* download_channel);
  void AddUrlRequest(unsigned int symbol, MSG_Request_Param param);
  void CancelUrlRequest(unsigned int symbol);
	DownloadChannel* download_channel_;
};

DownloadChannel::IORequest::IORequest(DownloadChannel* download_channel) {
	download_channel_ = download_channel;
}

void DownloadChannel::IORequest::AddUrlRequest(unsigned int symbol, MSG_Request_Param param) {
  download_channel_->InternalCheckCreate();
  uint32 process = ::GetCurrentProcessId();
  download_channel_->Send(new MSG_Request(MSG_ROUTING_NONE, symbol, param));
}

void DownloadChannel::IORequest::CancelUrlRequest(unsigned int symbol) {
  download_channel_->Send(new MSG_Cancel(MSG_ROUTING_NONE, symbol));
}

// DownloadChannel
DownloadChannel::DownloadChannel() {
  notify_delegate_ = NULL;
}

// IDownloadProxy method
void DownloadChannel::SetNotifyDelegate(NotifyDelegate* delegate) {
  notify_delegate_ = delegate;
}

void DownloadChannel::AddUrlRequest(unsigned int symbol, const UrlRequestData* data) {
  DCHECK(message_loop_);
  MSG_Request_Param param;
  param.request_url   =  data->request_url;
  param.save_path     =  data->save_path;
  param.start_position   =  data->start_position;
  message_loop_->PostTask(
      FROM_HERE, base::Bind(&IORequest::AddUrlRequest,
                            new IORequest(this), symbol, param));
}

void DownloadChannel::CancelUrlRequest(unsigned int symbol) {
  message_loop_->PostTask(
      FROM_HERE, base::Bind(&IORequest::CancelUrlRequest,
                            new IORequest(this), symbol));
}

std::wstring DownloadChannel::GetLaunchFile() const {
	return L"download.exe";
}

bool DownloadChannel::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(DownloadChannel, message)
    IPC_MESSAGE_HANDLER(MSG_Response, OnRequestResponse)
    IPC_MESSAGE_HANDLER(MSG_Progress, OnRequestProgress)
    IPC_MESSAGE_HANDLER(MSG_Finished, OnRequestFinished)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

// 请求的回复处理
void DownloadChannel::OnRequestResponse(unsigned int symbol, MSG_Response_Param param) {
  if (notify_delegate_) {
    UrlResponseData data;
    data.response_code = param.response_code;
    notify_delegate_->OnNotifyResponse(symbol, data);
  }
}

// 请求的进度处理
void DownloadChannel::OnRequestProgress(unsigned int symbol, MSG_Progress_Param param) {
  if (notify_delegate_) {
    ProgressData data;
    data.already_bytes  =  param.already_bytes;
    data.total_bytes    =  param.total_bytes;
    data.bytes_per_sec  =  param.bytes_per_sec;
    notify_delegate_->OnNotifyProgress(symbol, data);
  }
}

// 请求完成处理
void DownloadChannel::OnRequestFinished(unsigned int symbol, MSG_Finished_Param param) {
  if (notify_delegate_) {
    FinishData data;
    data.error_code  =  param.error_code;
    wcsncpy_s(data.error_desc, param.error_desc.c_str(), _countof(data.error_desc) - 1);
    notify_delegate_->OnNotifyFinished(symbol, data);
  }
}
